<template>
  <div class="tem-table">
    <div class="top-header">
      <el-input style="width: 260px" v-model="filterText" placeholder="关键词搜索"/>
      &nbsp;&nbsp;
      <el-button type="primary" @click="onInsert">新增</el-button>
      &nbsp;
      <el-button type="info" @click="onExportSettings()">导出配置</el-button>
      &nbsp;
      <el-button type="danger" :disabled="waitDelNode.size===0" @click="()=>onDel(waitDelNode)">删除</el-button>
    </div>
    <div class="tree-box">
      <el-tree
          :data="permStrTreeData"
          ref="treeRef"
          node-key="id"
          :highlight-current="true"
          default-expand-all
          @check-change="onCheckChange"
          :show-checkbox="true"
          :filter-node-method="filterNode"
          :props="{label: 'title'}"
          v-loading="loading"
          :expand-on-click-node="false"
      >
        <template #default="{ node, data }">
              <span class="custom-tree-node">
                <span style="color: black">
                  <span :style="{display: data.title?'inline':'none'}">{{ data.title }}&nbsp;</span>
                  <span style="color: green">[{{ data.symbolStr }}]</span>
                </span>
                <span>
                  <a @click="onEdit(data)" style="color: #2c75e6">&nbsp;编辑权限标识符&nbsp;</a>
                </span>
              </span>
        </template>
      </el-tree>
    </div>
  </div>

  <el-dialog
      title="新建权限标识符"
      v-model="showDialog"
      style="width: 500px"
      destroy-on-close
  >
    <el-form label-width="80px">
      <el-form-item label="菜单：">
        <el-tree-select
            style="width: 100%;"
            placeholder="请选择菜单"
            v-model="editForm.menuId"
            clearable
            node-key="id"
            :data="menuTree"
            :props="{label: 'title'}"
            :render-after-expand="false"
            @change="onUpdateMenuId"
            show-checkbox
        />
      </el-form-item>
      <el-form-item label="标识符：">
        <el-tag
            v-for="tag in editForm.symbolStr"
            :key="tag"
            class="mx-1"
            style="margin-bottom: 5px"
            :disable-transitions="false"
        >
          {{ tag }}
        </el-tag>
        <el-input
            v-if="inputVisible"
            ref="InputRef"
            v-model="inputValue"
            class="ml-1 w-20"
            placeholder="请输入"
            style="margin-bottom: 5px"
            size="small"
            @keyup.enter="handleInputConfirm"
            @blur="handleInputConfirm"
        />
        <el-button
            v-else
            class="button-new-tag ml-1"
            style="margin-bottom: 5px"
            size="small"
            @click="showInput">
          + New Tag
        </el-button>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button type="primary" @click="editData">提交</el-button>
    </template>
  </el-dialog>

  <el-dialog
      title="编辑权限标识符"
      v-model="showUpdatePermStr"
      style="width: 500px"
      destroy-on-close
  >
    <el-form label-width="80px">
      <el-form-item label="标识符：">
        <el-input v-model="updatePermStrData.symbolStr" placeholder="请输入标识符" style="width: 300px"
                  clearable></el-input>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button type="primary" @click="onUpdatePermStr">提交</el-button>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import {onBeforeMount, nextTick, ref, watch} from "vue";
import {ElInput, ElMessage, ElMessageBox, ElTree} from 'element-plus'
import {MenuMo} from "@/service/entity/MenuMo";
import {
  delAppPermStr, updatePermStr,
  editAppPermStr,
  EditAppPermStrArgs,
  getAppMenuList,
  getPermStrTreeData, getMenuLeafPermStrList, exportAppSettingsInsertSql
} from "@/service/AppManager";
import {PermStrDao} from "@/service/entity/PermStrDao";

const props = defineProps<{
  appId: any
}>()

onBeforeMount(async () => {
  fetchData()
  const res = await getAppMenuList(props.appId)
  menuTree.value = res.arr
})


const loading = ref(false)
const treeRef = ref<InstanceType<typeof ElTree>>()
const filterText = ref('')
watch(filterText, (val) => {
  treeRef.value!.filter(val)
})
const waitDelNode = ref(new Set([]))
const showUpdatePermStr = ref(false)
const updatePermStrData = reactive<PermStrDao>({
  id: undefined,
  title: undefined,
  symbolStr: undefined,
  parentId: undefined,
  isMenu: undefined,
  children: []
})
const permStrTreeData = ref<PermStrDao[]>([])
const showDialog = ref(false)
const menuTree = ref<MenuMo[]>([])
const editForm = reactive<EditAppPermStrArgs>({
  appId: '',
  menuId: '',
  symbolStr: []
})

const onUpdateMenuId = async () => {
  if (editForm.menuId) {
    const res = await getMenuLeafPermStrList(editForm.menuId)
    if (res) {
      editForm.symbolStr = res.arr
    }
  }
}

const inputValue = ref('')
const inputVisible = ref(false)
const InputRef = ref<InstanceType<typeof ElInput>>()


const showInput = () => {
  inputVisible.value = true
  nextTick(() => {
    InputRef.value!.input!.focus()
  })
}

const handleInputConfirm = () => {
  const val = inputValue.value.trim()
  if (!val) return
  editForm.symbolStr.push(val)
  inputVisible.value = false
  inputValue.value = ''
}

const fetchData = async () => {
  loading.value = true
  try {
    const res = await getPermStrTreeData(props.appId)
    if (!res) return
    permStrTreeData.value = res.arr
  } finally {
    setTimeout(() => loading.value = false, 200)
  }

}

const onCheckChange = (p1, p2, p3) => {
  if (!p1.isMenu) {
    const arr = [...waitDelNode.value]
    if (p2) {
      arr.push(p1.id)
      waitDelNode.value = new Set(arr)
    } else {
      const idx = arr.indexOf(p1.id)
      if (idx !== -1) {
        arr.splice(idx, 1)
        waitDelNode.value = new Set(arr)
      }
    }
  }

}

const onInsert = () => {
  editForm.appId = props.appId
  editForm.menuId = ''
  editForm.symbolStr = []
  showDialog.value = true
}

const onEdit = async (data: PermStrDao) => {
  showUpdatePermStr.value = true
  updatePermStrData.symbolStr = data.symbolStr
  updatePermStrData.isMenu = data.isMenu
  updatePermStrData.id = data.id
}

const onDel = async (data: any[]) => {
  ElMessageBox.confirm(
      '永久删除该条信息. 是否确认?',
      '警告',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      }
  ).then(async () => {
    const res = await delAppPermStr(props.appId, [...waitDelNode.value])
    if (res) {
      waitDelNode.value = new Set([])
      fetchData()
    }
  }).catch(() => {
    ElMessage({
      type: 'info',
      message: '取消删除',
    })
  })
}

const editData = async () => {
  if (!editForm.menuId) {
    ElMessage.error('请选择菜单')
    return
  }
  const res = await editAppPermStr(editForm)
  if (!res) {
    return
  }
  ElMessage({
    type: 'success',
    message: '提交成功！',
  })
  showDialog.value = false
  fetchData()
}

const onUpdatePermStr = async () => {
  const res = await updatePermStr({
    id: updatePermStrData.id,
    isMenu: updatePermStrData.isMenu,
    symbolStr: updatePermStrData.symbolStr
  })
  if (!res) return
  ElMessage({
    type: 'success',
    message: '提交成功！',
  })
  fetchData()
  showUpdatePermStr.value = false
}

//搜索树
const filterNode = (value, data) => {
  if (!value) return true
  return `${data.title}-${data.symbolStr}`.includes(value)
}

const onExportSettings = async () => {
  await exportAppSettingsInsertSql(props.appId,localStorage.getItem('appName'));
}

</script>

<style scoped lang="scss">
@import "@/global.scss";

.tem-table {
  height: 100%;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  padding: 10px;

  .top-header {
    display: flex;
    justify-content: flex-end;
  }

  .tree-box {
    width: 600px;
    flex: 1;
    overflow: auto;
  }
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 16px;
  padding: 10px 0px;
  padding-right: 8px;

}


.tem-table-box {
  flex: 1;
  overflow: hidden;
}
</style>